<!DOCTYPE html>
<html lang="en">
<head>
  <!-- 设置文档编码和视口 -->
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Tablet MindMap with Markmap</title>
  
  <!-- 引入 markmap-view 的样式 -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/markmap-view@0.15.3/dist/style.css" />
  
  <!-- 引入必要的 JavaScript 库 -->
  <script src="d3@6.js"></script>
  <script src="markmap-lib@0.18"></script>
  <script src="markmap-view@0.18"></script>
  
  <!-- 引入 Font Awesome 图标库 -->
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
  />
  
  <!-- 页面内联样式 -->
  <style>
    /* 全局样式重置，保证所有元素的 box-sizing 和内外边距统一 */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    /* body 样式，设置字体、背景色、文本颜色及布局属性 */
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f5f7fa;
      color: #333;
      height: 100vh;
      overflow: hidden;
      touch-action: manipulation;
    }
    /* 主容器，使用 flex 布局分为左右两个部分 */
    .container {
      display: flex;
      flex-direction: row;
      height: 100vh;
      width: 100vw;
    }
    /* Markdown 编辑器面板，设置宽度比例、背景及边框 */
    .editor-panel {
      flex: 1.1 1 0;
      display: flex;
      flex-direction: column;
      background: #fff;
      border-right: 1px solid #e0e0e0;
      min-width: 240px;
      max-width: 520px;
    }
    /* 思维导图展示面板 */
    .mindmap-panel {
      flex: 2 1 0;
      display: flex;
      flex-direction: column;
      background: #f8f9fa;
      min-width: 0;
    }
    /* 面板头部样式，包括标题和按钮 */
    .panel-header {
      padding: 14px 20px;
      background: #4a6491;
      color: white;
      display: flex;
      justify-content: space-between;
      align-items: center;
      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    /* 面板标题样式 */
    .panel-title {
      font-size: 1.4rem;
      font-weight: 600;
      display: flex;
      align-items: center;
      gap: 12px;
    }
    .panel-title i {
      font-size: 1.6rem;
    }
    /* 工具栏样式，包含按钮和其他控件 */
    .toolbar {
      display: flex;
      gap: 12px;
      padding: 14px;
      background: #f8f9fa;
      border-bottom: 1px solid #e0e0e0;
      flex-wrap: wrap;
    }
    /* 工具按钮样式 */
    .tool-btn {
      background: white;
      border: 1px solid #ddd;
      border-radius: 10px;
      padding: 12px 18px;
      cursor: pointer;
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 16px;
      color: #444;
      transition: all 0.2s;
      min-height: 50px;
      min-width: 50px;
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
    }
    /* 鼠标悬停按钮时的样式 */
    .tool-btn:hover {
      background: #4a6491;
      color: white;
      border-color: #4a6491;
    }
    .tool-btn i {
      font-size: 20px;
    }
    /* Markdown 输入框样式 */
    #markdown-input {
      flex: 1;
      width: 100%;
      padding: 18px;
      border: none;
      font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
      font-size: 16px;
      line-height: 1.6;
      resize: none;
      background: #fff;
      border-bottom: 1px solid #e0e0e0;
    }
    /* markmap 容器，用于放置生成的 SVG 思维导图 */
    #markmap-container {
      flex: 1;
      background: #fff;
      position: relative;
      overflow: hidden;
      min-height: 0;
    }
    /* 使 SVG 能够充满容器 */
    #markmap-container svg {
      width: 100%;
      height: 100%;
    }
    /* 状态条样式，用于显示提示信息 */
    .status-bar {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      padding: 14px 20px;
      background: #2ecc71;
      color: white;
      font-size: 16px;
      text-align: center;
      z-index: 1000;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
      transform: translateY(-100%);
      transition: transform 0.3s ease;
    }
    /* 错误状态条样式 */
    .status-bar.error {
      background: #e74c3c;
    }
    /* 当状态条显示时，设置 translate 属性 */
    .status-bar.show {
      transform: translateY(0);
    }
    /* 缩放控制按钮容器样式 */
    .zoom-controls {
      position: absolute;
      bottom: 25px;
      right: 25px;
      display: flex;
      flex-direction: column;
      gap: 15px;
      z-index: 100;
    }
    /* 缩放按钮基础样式 */
    .zoom-btn {
      width: 55px;
      height: 55px;
      border-radius: 50%;
      background: white;
      border: 1px solid #ddd;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
      color: #444;
      transition: all 0.2s;
      font-size: 22px;
    }
    /* 缩放按钮鼠标悬停样式 */
    .zoom-btn:hover {
      background: #4a6491;
      color: white;
      transform: scale(1.1);
    }
    /* 复选框容器样式 */
    .checkbox-container {
      display: flex;
      align-items: center;
      gap: 12px;
      background: white;
      padding: 12px 18px;
      border-radius: 10px;
      border: 1px solid #ddd;
      min-height: 50px;
    }
    .checkbox-container label {
      font-size: 16px;
      font-weight: 500;
      color: #444;
    }
    
    /* 针对屏幕宽度小于768px的响应式设计，隐藏部分文字 */
    @media (max-width: 768px) {
      .tool-btn span {
        display: none;
      }
      .tool-btn {
        padding: 14px;
      }
      .panel-title span {
        display: none;
      }
      .panel-title i {
        font-size: 1.8rem;
      }
    }
  </style>
</head>
<body>
  <!-- 主容器，将编辑器和思维导图面板并列展示 -->
  <div class="container">
    <!-- Markdown 编辑器面板 -->
    <div class="editor-panel">
      <!-- 编辑器头部，只保留功能按钮图标，左右排布 -->
      <div class="panel-header" style="justify-content: space-between;">
        <button class="tool-btn" id="sample-btn" title="Load Sample">
          <i class="fas fa-file-code"></i>
        </button>
        <button class="tool-btn" id="clear-btn" title="Clear">
          <i class="fas fa-trash"></i>
        </button>
      </div>
      <!-- 工具栏：包含转换按钮和自动转换复选框 -->
      <div class="toolbar">
        <button class="tool-btn" id="convert-btn">
          <i class="fas fa-sync-alt"></i> <span>Convert</span>
        </button>
        <div class="checkbox-container">
          <input type="checkbox" id="auto-convert" checked />
          <label for="auto-convert">Auto Convert</label>
        </div>
      </div>
      <!-- Markdown 输入框 -->
      <textarea id="markdown-input" placeholder="Enter your Markdown here..."></textarea>
    </div>

    <!-- 思维导图展示面板 -->
    <div class="mindmap-panel">
      <!-- 面板头部，只保留功能按钮图标，左右排布 -->
      <div class="panel-header" style="justify-content: space-between;">
        <button class="tool-btn" id="save-btn" title="Save">
          <i class="fas fa-save"></i>
        </button>
        <button class="tool-btn" id="export-btn" title="Export">
          <i class="fas fa-file-export"></i>
        </button>
      </div>

      <!-- markmap 容器，用于放置生成的 SVG 思维导图 -->
      <div id="markmap-container"></div>

      <!-- 缩放控制按钮 -->
      <div class="zoom-controls">
        <button class="zoom-btn" id="zoom-in" title="Zoom In">
          <i class="fas fa-plus"></i>
        </button>
        <button class="zoom-btn" id="zoom-out" title="Zoom Out">
          <i class="fas fa-minus"></i>
        </button>
        <button class="zoom-btn" id="zoom-reset" title="Reset Zoom">
          <i class="fas fa-expand"></i>
        </button>
      </div>
    </div>
  </div>

  <!-- 脚本部分，主要实现 Markdown 转思维导图的功能 -->
  <script>
    // 当页面 DOM 完全加载后执行
    document.addEventListener('DOMContentLoaded', function () {
      // 获取页面中各个 DOM 元素的引用
      const markdownInput = document.getElementById('markdown-input');
      const markmapContainer = document.getElementById('markmap-container');
      const convertBtn = document.getElementById('convert-btn');
      const autoConvertCheckbox = document.getElementById('auto-convert');
      const sampleBtn = document.getElementById('sample-btn');
      const clearBtn = document.getElementById('clear-btn');
      const saveBtn = document.getElementById('save-btn');
      const exportBtn = document.getElementById('export-btn');
      const zoomIn = document.getElementById('zoom-in');
      const zoomOut = document.getElementById('zoom-out');
      const zoomReset = document.getElementById('zoom-reset');

      // 定时器，用于自动转换 Markdown 内容
      let convertTimeout;
      // markmap 实例和 SVG 元素引用
      let markmapInstance = null;
      let svgElement = null;

      // 示例 Markdown 数据，用于初始加载和测试
      const sampleMarkdown = `# Project Plan

## Goals
- Increase productivity
- Improve team collaboration
- Enhance product quality

## Tasks
1. Research phase
    - Market analysis
    - Competitor study
2. Development
    - Backend API
    - Frontend UI
3. Testing
    - Unit tests
    - Integration tests

## Timeline
- Q1: Planning
- Q2: Development
- Q3: Testing
- Q4: Launch

## Team
- Product Manager
- Developers
    - Frontend
    - Backend
- Designers
- QA Engineers

## Budget
- Funding: $500,000
- Expenses: $450,000
- Contingency: $50,000

## Risks
- Market changes
- Technical challenges
- Resource limitations`;

      // 将 Markdown 转换为思维导图并渲染
      function convertMarkdown() {
        const text = markdownInput.value.trim();
        if (!text) {
            showStatus('Editor is empty');
            return;
        }

        try {
            const transformer = new markmap.Transformer();
            const { root } = transformer.transform(text);
            markmapContainer.innerHTML = '';
            
            svgElement = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svgElement.id = 'markmap-svg';
            svgElement.style.width = '100%';
            svgElement.style.height = '100%';
            markmapContainer.appendChild(svgElement);
            
            // 创建Markmap实例时启用缩放和平移功能
            markmapInstance = markmap.Markmap.create(svgElement, {
                // 启用缩放和平移
                zoom: true,
                pan: true
            }, root);
            
            // 初始化缩放控制按钮的事件
            setupZoomControls();
            
            showStatus('Converted successfully');
        } catch (error) {
            console.error('Error converting Markdown:', error);
            showStatus(`Conversion failed: ${error.message}`, true);
        }
    }

    function setupZoomControls() {
        if (!markmapInstance || !markmapInstance.zoom) return;
        
        // 确保zoom对象存在
        const zoom = markmapInstance.zoom;
        
        // 点击放大按钮
        zoomIn.onclick = () => {
            zoom.scaleBy(1.2);
            zoom.scaleBy(1.2);  // 修复拼写错误
        };
        
        // 点击缩小按钮
        zoomOut.onclick = () => {
            zoom.scaleBy(0.8);
        };
        
        // 点击重置按钮
        zoomReset.onclick = () => {
            zoom.scaleTo(1);
            zoom.translateTo(0, 0);
        };
    }

      // 显示提示状态条
      function showStatus(message, isError = false) {
        // 创建提示状态条 DOM 元素
        const statusBar = document.createElement('div');
        statusBar.className = 'status-bar';
        if (isError) statusBar.classList.add('error');
        statusBar.textContent = message;
        statusBar.classList.add('show');
        document.body.appendChild(statusBar);
        // 3秒后自动隐藏提示信息
        setTimeout(() => {
          statusBar.classList.remove('show');
          setTimeout(() => {
            document.body.removeChild(statusBar);
          }, 300);
        }, 3000);
      }

      // 设置缩放控制按钮的事件绑定
      function setupZoomControls() {
        if (!markmapInstance) return;
        
        // 点击放大按钮，按照 1.2 倍缩放
        zoomIn.onclick = () => markmapInstance.zoom.scaleBy(1.2);
        // 点击缩小按钮，按照 0.8 倍缩放
        zoomOut.onclick = () => markmapInstance.zoom.scaleBy(0.8);
        // 点击重置按钮，恢复初始缩放和位移
        zoomReset.onclick = () => {
          markmapInstance.zoom.scaleTo(1);
          markmapInstance.zoom.translateTo(0, 0);
        };
      }

      // 为各个按钮绑定点击事件
























      // 示例按钮：加载示例 Markdown 内容并自动转换（如果复选框选中）
      sampleBtn.addEventListener('click', () => {
        markdownInput.value = sampleMarkdown;
        if (autoConvertCheckbox.checked) {
          convertMarkdown();
        }
      });

      // 清空按钮：清空输入框内容，根据复选框状态进行处理
      clearBtn.addEventListener('click', () => {
        markdownInput.value = '';
        if (autoConvertCheckbox.checked) {
          convertMarkdown();
        } else {
          markmapContainer.innerHTML = '';
          showStatus('Editor cleared');
        }
      });

      // 输入框输入事件：支持自动转换 Markdown（防抖动处理）
      markdownInput.addEventListener('input', () => {
        if (autoConvertCheckbox.checked) {
          clearTimeout(convertTimeout);
          convertTimeout = setTimeout(convertMarkdown, 800);
        }
      });

      // 转换按钮点击事件，手动触发 Markdown 转换
      convertBtn.addEventListener('click', convertMarkdown);

      // 保存按钮：将当前 Markdown 保存到 localStorage 中
      saveBtn.addEventListener('click', () => {
        const text = markdownInput.value.trim();
        if (text) {
          localStorage.setItem('md2mind_data', text);
          showStatus('MindMap saved successfully');
        } else {
          showStatus('No mindmap data to save', true);
        }
      });

      // 导出按钮：将当前 Markdown 内容导出为 .md 文件
      exportBtn.addEventListener('click', () => {
        const text = markdownInput.value.trim();
        if (text) {
          // 使用 data URI 方案生成文件下载链接
          const dataStr = 'data:text/markdown;charset=utf-8,' + encodeURIComponent(text);
          const downloadAnchor = document.createElement('a');
          downloadAnchor.setAttribute('href', dataStr);
          downloadAnchor.setAttribute('download', 'mindmap.md');
          document.body.appendChild(downloadAnchor);
          downloadAnchor.click();
          downloadAnchor.remove();
          showStatus('MindMap exported');
        } else {
          showStatus('No mindmap data to export', true);
        }
      });

      // 页面初始化：尝试从 localStorage 获取保存的 Markdown 数据
      const savedData = localStorage.getItem('md2mind_data');
      if (savedData) {
        markdownInput.value = savedData;
        showStatus('Loaded saved data');
      } else {
        // 如果没有保存数据，则加载示例 Markdown
        markdownInput.value = sampleMarkdown;
      }
      
      // 延时初始渲染 Markdown 到思维导图
      setTimeout(convertMarkdown, 100);
    });
  </script>
</body>
</html>